package at.fhj.itm11.forum.beans;

import java.io.IOException;
import java.io.Serializable;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpSession;
import javax.xml.rpc.ServiceException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import at.fhj.itm11.forum.service.UserService;
import at.fhj.itm11.forum.service.dtos.UserDTO;
import at.fhj.itm11.forum.util.ForumConstants;
import at.fhj.itm11.forum.ws.FHJForumAuthWS_ServiceLocator;

/*
 * Pay attention to correct imports!
 */
@Named
@ManagedBean
@RequestScoped
public class AuthenticationBean implements Serializable { // Interface!

	private final Logger logger = LoggerFactory.getLogger(getClass());

	// Use GENERATED ID!
	private static final long serialVersionUID = 6330218001922560054L;

	@Inject
	@Named("userServiceImpl")
	private UserService userService;

	private FacesContext facesContext = FacesContext.getCurrentInstance();
	private ExternalContext externalContext;
	private HttpSession session;

	private String username;
	private String password;
	private String redirectPath = ForumConstants.TARGET_LOGIN_OK;

	private UserDTO currentUser;

	/*
	 * Constructor Method
	 */
	@PostConstruct
	public void init() {
		externalContext = facesContext.getExternalContext();
		session = (HttpSession) externalContext.getSession(true);
		
		userService.setServiceLocator(new FHJForumAuthWS_ServiceLocator());
	}

	/**
	 * Performs the web service call to the user authentication server and
	 * processes the response accordingly.
	 * 
	 * @param actionEvent
	 *            Used for JSF
	 * @throws ServiceException
	 * @throws IOException
	 */
	public void login(ActionEvent actionEvent) {
		FacesMessage msg = null;

		UserDTO user = userService.login(username, password);

		try {
			if (user != null) {
				session.setAttribute(ForumConstants.SESSION_CURRENT_USER, user);
				setCurrentUser(user);
				externalContext.redirect(redirectPath);
			} else {
				msg = new FacesMessage(FacesMessage.SEVERITY_WARN,
						"Login Error", "Benutzername oder Passwort ungültig");
			}
		} catch (IOException e) {
			logger.error("An error occured while login", e);
			msg = new FacesMessage(
					FacesMessage.SEVERITY_ERROR,
					"Login Error",
					"Sie konnten leider nicht angemeldet werden, bitte versuchen Sie es später nochmal");
		}

		if (msg != null) {
			facesContext.addMessage(null, msg);
		}
	}

	public void logout(ActionEvent actionEvent) {
		// delete current user from session
		session.removeAttribute(ForumConstants.SESSION_CURRENT_USER);
		setCurrentUser(null);
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public UserDTO getCurrentUser() {
		if (currentUser == null) {
			currentUser = (UserDTO) session
					.getAttribute(ForumConstants.SESSION_CURRENT_USER);
		}

		return currentUser;
	}

	public void setCurrentUser(UserDTO currentUser) {
		this.currentUser = currentUser;
	}

	public HttpSession getSession() {
		return session;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public void setExternalContext(ExternalContext externalContext) {
		this.externalContext = externalContext;
	}

	public void setSession(HttpSession session) {
		this.session = session;
	}

	public void setFacesContext(FacesContext facesContext) {
		this.facesContext = facesContext;
	}

	public void setRedirectPath(String redirectPath) {
		this.redirectPath = redirectPath;
	}

	public ExternalContext getExternalContext() {
		return externalContext;
	}

}
